Getting Started with React
Must Watch!
React is a JavaScript library for building user interfaces.
React is used to build single page applications.
React allows us to create reusable UI components.
Getting Started with React
- Static HTML File
https://www.taniarascia.com/blog
https://www.taniarascia.com/getting-started-with-react/
Let's start by making a basic index.html
file.
We're going to load in three CDNs in the head
- React, React DOM, and Babel.
We're also going to make a div
with an id called root
, and finally we'll create a script
tag where your custom code will live.
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Hello React!</title>
<script src="https://unpkg.com/react@^16/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16.13.0/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/babel-standalone@6.26.0/babel.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
// React code will go here
</script>
</body>
</html>
I'm loading in the latest stable versions of the libraries as of the time of this writing.
React - the React top level API
React DOM - adds DOM-specific methods
Babel - a JavaScript compiler that lets us use ES6+ in old browsers
The entry point for our app will be the root
div element, which is named by convention.
You'll also notice the text/babel
script type, which is mandatory for using Babel.
Now, let's write our first code block of React.
We're going to use ES6 classes to create a React component called App
.
index.html
class App extends React.Component {
//...
}
Now we'll add the render()
method, the only required method in a class component, which is used to render DOM nodes.
index.html
class App extends React.Component {
render() {
return ( //...
);
}
}
Inside the return
, we're going to put what looks like a simple HTML element.
Note that we're not returning a string here, so don't use quotes around the element.
This is called JSX
, and we'll learn more about it soon.
index.html
class App extends React.Component {
render() {
return <h1>Hello world!</h1>
}
}
Finally, we're going to use the React DOM render()
method to render the App
class we created into the root
div in our HTML.
index.html
ReactDOM.render(<App />, document.getElementById('root'))
Here is the full code for our index.html
.
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Hello React!</title>
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6.26.0/babel.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
class App extends React.Component { render() { return <h1>Hello world!</h1> }
}
ReactDOM.render(<App />, document.getElementById('root'))
</script>
</body>
</html>
Now if you view your index.html
in the browser, you'll see the h1
tag we created rendered to the DOM.
- Create React App
To set up create-react-app
, run the following code in your terminal, one directory up from where you want the project to live.
look react-tutorial inside user folder
npx create-react-app react-tutorial
Once that finishes installing, move to the newly created directory and start the project.
cd react-tutorial
npm start
Once you run this command, a new window will popup at localhost:3000
with your new React app.
Create React App is very good for getting started for beginners as well as large-scale enterprise applications, but it's not perfect for every workflow.
You can also create your own Webpack setup for React.
If you look into the project structure, you'll see a /public
and /src
directory, along with the regular node_modules
, .gitignore
, README.md
, and package.json
.
In /public
, our important file is index.html
, which is very similar to the static index.html
file we made earlier - just a root
div.
This time, no libraries or scripts are being loaded in.
The /src
directory will contain all our React code.
To see how the environment automatically compiles and updates your React code, find the line that looks like this in /src/App.js
:
To get started, edit `src/App.js` and save to reload.
And replace it with any other text.
Once you save the file, you'll notice localhost:3000
compiles and refreshes with the new data.
Go ahead and delete all the files out of the /src
directory, and we'll create our own boilerplate file without any bloat.
We'll just keep index.css
and index.js
.
For index.css
, I just copy-and-pasted the contents of Primitive CSS into the file.
If you want, you can use Bootstrap or whatever CSS framework you want, or nothing at all.
I just find it easier to work with.
Now in index.js
, we're importing React, ReactDOM, and the CSS file.
src/index.js
import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
Let's create our App
component again.
Before, we just had an <h1>
, but now I'm adding in a div element with a class as well.
You'll notice that we use className
instead of class
.
This is our first hint that the code being written here is JavaScript, and not actually HTML.
src/index.js
class App extends Component {
render() {
return (
<div className="App"> <h1>Hello, React!</h1>
</div>
)
}
}
Finally, we'll render the App
to the root as before.
src/index.js
ReactDOM.render(<App />, document.getElementById('root'))
Here's our full index.js
.
This time, we're loading the Component
as a property of React, so we no longer need to extend React.Component
.
src/index.js
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import './index.css'
class App extends Component {
render() {
return (
<div className="App"> <h1>Hello, React!</h1>
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('root'))
If you go back to localhost:3000
, you'll see "Hello, React!" just like before.
We have the beginnings of a React app now.
- React Developer Tools
There is an extension called React Developer Tools that will make your life much easier when working with React.
Download React DevTools for Chrome, or whatever browser you prefer to work on.
After you install it, when you open DevTools, you'll see a tab for React.
Click on it, and you'll be able to inspect components as they're written.
You can still go to the Elements tab to see the actual DOM output.
It may not seem like that much of a deal now, but as the app gets more complicated, it will become increasingly necessary to use.
Now we have all the tools and setup we need to actually begin working with React.
JSX: JavaScript + XML
JSX stands for JavaScript XML.
With JSX, we can write what looks like HTML, and also we can create and use our own XML-like tags.
Here's what JSX looks like assigned to a variable.
JSX
const heading = <h1 className="site-heading">Hello, React</h1>
Using JSX is not mandatory for writing React.
Under the hood, it's running createElement
, which takes the tag, object containing the properties, and children of the component and renders the same information.
The below code will have the same output as the JSX above.
No JSX
const heading = React.createElement('h1', { className: 'site-heading' }, 'Hello, React!')
JSX is actually closer to JavaScript, not HTML, so there are a few key differences to note when writing it.
className
is used instead of class
for adding CSS classes, as class
is a reserved keyword in JavaScript.
Properties and methods in JSX are camelCase - onclick
will become onClick
.
Self-closing tags must end in a slash - e.g. <img />
JavaScript expressions can also be embedded inside JSX using curly braces, including variables, functions, and properties.
const name = 'Tania'
const heading = <h1>Hello, {name}</h1>
JSX is easier to write and understand than creating and appending many elements in vanilla JavaScript, and is one of the reasons people love React so much.
Components
So far, we've created one component - the App
component.
Almost everything in React consists of components, which can be class components or simple components.
Most React apps have many small components, and everything loads into the main App
component.
Components also often get their own file, so let's change up our project to do so.
Remove the App
class from index.js
, so it looks like this.
src/index.js
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
import './index.css'
ReactDOM.render(<App />, document.getElementById('root'))
We'll create a new file called App.js
and put the component in there.
src/App.js
import React, { Component } from 'react'
class App extends Component {
render() {
return (
<div className="App"> <h1>Hello, React!</h1>
</div>
)
}
}
export default App
We export the component as App
and load it in index.js
.
It's not mandatory to separate components into files, but an application will start to get unwieldy and out-of-hand if you don't.
- Class Components
Let's create another component.
We're going to create a table.
Make Table.js
, and fill it with the following data.
src/Table.js
import React, { Component } from 'react'
class Table extends Component {
render() {
return (
<table> <thead> <tr> <th>Name</th> <th>Job</th> </tr> </thead> <tbody> <tr> <td>Charlie</td> <td>Janitor</td> </tr> <tr> <td>Mac</td> <td>Bouncer</td> </tr> <tr> <td>Dee</td> <td>Aspiring actress</td> </tr> <tr> <td>Dennis</td> <td>Bartender</td> </tr> </tbody>
</table>
)
}
}
export default Table
This component we created is a custom class component.
We capitalize custom components to differentiate them from regular HTML elements.
Back in App.js
, we can load in the Table, first by importing it in:
src/App.js
import Table from './Table'
Then by loading it into the render()
of App
, where before we had "Hello, React!".
I also changed the class of the outer container.
src/App.js
import React, { Component } from 'react'
import Table from './Table'
class App extends Component {
render() {
return (
<div className="container"> <Table />
</div>
)
}
}
export default App
If you check back on your live environment, you'll see the Table
loaded in.
Now we've seen what a custom class component is.
We could reuse this component over and over.
However, since the data is hard-coded into it, it wouldn't be too useful at the moment.
- Simple Components
The other type of component in React is the simple component, which is a function.
This component doesn't use the class
keyword.
Let's take our Table
and make two simple components for it - a table header, and a table body.
We're going to use ES6 arrow functions to create these simple components.
First, the table header.
src/Table.js
const TableHeader = () => {
return (
<thead>
<tr> <th>Name</th> <th>Job</th>
</tr>
</thead>
)
}
Then the body.
src/Table.js
const TableBody = () => {
return (
<tbody>
<tr> <td>Charlie</td> <td>Janitor</td>
</tr>
<tr> <td>Mac</td> <td>Bouncer</td>
</tr>
<tr> <td>Dee</td> <td>Aspiring actress</td>
</tr>
<tr> <td>Dennis</td> <td>Bartender</td>
</tr>
</tbody>
)
}
Now our Table
file will look like this.
Note that the TableHeader
and TableBody
components are all in the same file, and being used by the Table
class component.
src/Table.js
const TableHeader = () => { ...
}
const TableBody = () => { ...
}
class Table extends Component {
render() {
return (
<table> <TableHeader /> <TableBody />
</table>
)
}
}
Everything should appear as it did before.
As you can see, components can be nested in other components, and simple and class components can be mixed.
A class component must include render()
, and the return
can only return one parent element.
As a wrap up, let's compare a simple component with a class component.
Simple Component
const SimpleComponent = () => {
return <div>Example</div>
}
Class Component
class ClassComponent extends Component {
render() {
return <div>Example</div>
}
}
Note that if the return
is contained to one line, it does not need parentheses.
Props
Right now, we have a cool Table
component, but the data is being hard-coded.
One of the big deals about React is how it handles data, and it does so with properties, referred to as props, and with state.
Now, we'll focus on handling data with props.
First, let's remove all the data from our TableBody
component.
src/Table.js
const TableBody = () => {
return <tbody />
}
Then let's move all that data to an array of objects, as if we were bringing in a JSON-based API.
We'll have to create this array inside our render()
.
src/App.js
class App extends Component {
render() {
const characters = [
{ name: 'Charlie', job: 'Janitor',
},
{ name: 'Mac', job: 'Bouncer',
},
{ name: 'Dee', job: 'Aspring actress',
},
{ name: 'Dennis', job: 'Bartender',
},
]
return (
<div className="container"> <Table />
</div>
)
}
}
Now, we're going to pass the data through to the child component (Table
) with properties, kind of how you might pass data through using data-
attributes.
We can call the property whatever we want, as long as it's not a reserved keyword, so I'll go with characterData
.
The data I'm passing through is the characters
variable, and I'll put curly braces around it as it's a JavaScript expression.
src/App.js
return (
<div className="container">
<Table characterData={characters} />
</div>
)
Now that data is being passed through to Table
, we have to work on accessing it from the other side.
src/Table.js
class Table extends Component {
render() {
const { characterData } = this.props
return (
<table> <TableHeader /> <TableBody characterData={characterData} />
</table>
)
}
}
If you open up React DevTools and inspect the Table
component, you'll see the array of data in the property.
The data that's stored here is known as the virtual DOM, which is a fast and efficient way of syncing data with the actual DOM.
This data is not in the actual DOM yet, though.
In Table
, we can access all props through this.props
.
We're only passing one props through, characterData, so we'll use this.props.characterData
to retrieve that data.
I'm going to use the ES6 property shorthand to create a variable that contains this.props.characterData
.
const { characterData } = this.props
Since our Table
component actually consists of two smaller simple components, I'm going to pass it through to the TableBody
, once again through props.
src/Table.js
class Table extends Component {
render() {
const { characterData } = this.props
return (
<table> <TableHeader /> <TableBody characterData={characterData} />
</table>
)
}
}
Right now, TableBody
takes no parameters and returns a single tag.
src/Table.js
const TableBody = () => {
return <tbody />
}
We're going to pass the props through as a parameter, and map through the array to return a table row for each object in the array.
This map will be contained in the rows
variable, which we'll return as an expression.
src/Table.js
const TableBody = props => {
const rows = props.characterData.map((row, index) => {
return (
<tr key={index}> <td>{row.name}</td> <td>{row.job}</td>
</tr>
)
})
return <tbody>{rows}</tbody>
}
If you view the front end of the app, all the data is loading in now.
You'll notice I've added a key index to each table row.
You should always use keys when making lists in React, as they help identify each list item.
We'll also see how this is necessary in a moment when we want to manipulate list items.
Props are an effective way to pass existing data to a React component, however the component cannot change the props - they're read-only.
In the next section, we'll learn how to use state to have further control over handling data in React.
State
Right now, we're storing our character data in an array in a variable, and passing it through as props.
This is good to start, but imagine if we want to be able to delete an item from the array.
With props, we have a one way data flow, but with state we can update private data from a component.
You can think of state as any data that should be saved and modified without necessarily being added to a database - for example, adding and removing items from a shopping cart before confirming your purchase.
To start, we're going to create a state
object.
src/App.js
class App extends Component {
state = {}
}
The object will contain properties for everything you want to store in the state.
For us, it's characters
.
src/App.js
class App extends Component {
state = {
characters: [],
}
}
Move the entire array of objects we created earlier into state.characters
.
src/App.js
class App extends Component {
state = {
characters: [
{ name: 'Charlie', // the rest of the data
},
],
}
}
Our data is officially contained in the state.
Since we want to be able to remove a character from the table, we're going to create a removeCharacter
method on the parent App
class.
To retrieve the state, we'll get this.state.characters
using the same ES6 method as before.
To update the state, we'll use this.setState()
, a built-in method for manipulating state.
We'll filter the array based on an index
that we pass through, and return the new array.
You must use this.setState()
to modify an array.
Simply applying a new value to this.state.property
will not work.
src/App.js
removeCharacter = index => {
const { characters } = this.state
this.setState({
characters: characters.filter((character, i) => {
return i !== index
}),
})
}
filter
does not mutate but rather creates a new array, and is a preferred method for modifying arrays in JavaScript.
This particular method is testing an index vs.
all the indices in the array, and returning all but the one that is passed through.
Now we have to pass that function through to the component, and render a button next to each character that can invoke the function.
We'll pass the removeCharacter
function through as a prop to Table
.
src/App.js
render() {
const { characters } = this.state
return (
<div className="container">
<Table characterData={characters} removeCharacter={this.removeCharacter} />
</div>
)
}
Since we're passing it down to TableBody
from Table
, we're going to have to pass it through again as a prop, just like we did with the character data.
In addition, since it turns out that the only components having their own states in our project are App
and Form
, it would be best practice to transform Table
into a simple component from the class component it currently is.
src/Table.js
const Table = props => {
const { characterData, removeCharacter } = props
return (
<table>
<TableHeader />
<TableBody characterData={characterData} removeCharacter={removeCharacter} />
</table>
)
}
Here's where that index we defined in the removeCharacter()
method comes in.
In the TableBody
component, we'll pass the key/index through as a parameter, so the filter function knows which item to remove.
We'll create a button with an onClick
and pass it through.
src/Table.js
<tr key={index}>
<td>{row.name}</td>
<td>{row.job}</td>
<td>
<button onClick={() => props.removeCharacter(index)}>Delete</button>
</td>
</tr>
The onClick
function must pass through a function that returns the removeCharacter()
method, otherwise it will try to run automatically.
Awesome.
Now we have delete buttons, and we can modify our state by deleting a character.
I deleted Mac.
Now you should understand how state gets initialized and how it can be modified.
Submitting Form Data
Now we have data stored in state, and we can remove any item from the state.
However, what if we wanted to be able to add new data to state? In a real world application, you'd more likely start with empty state and add to it, such as with a to-do list or a shopping cart.
Before anything else, let's remove all the hard-coded data from state.characters
, as we'll be updating that through the form now.
src/App.js
class App extends Component {
state = {
characters: [],
}
}
Now let's go ahead and create a Form
component in a new file called Form.js
.
We're going to set the initial state of the Form
to be an object with some empty properties, and assign that initial state to this.state
.
src/Form.js
import React, { Component } from 'react'
class Form extends Component {
initialState = {
name: '',
job: '',
}
state = this.initialState
}
Previously, it was necessary to include a constructor()
on React class components, but it's not required anymore.
Our goal for this form will be to update the state of Form
every time a field is changed in the form, and when we submit, all that data will pass to the App
state, which will then update the Table
.
First, we'll make the function that will run every time a change is made to an input.
The event
will be passed through, and we'll set the state of Form
to have the name
(key) and value
of the inputs.
src/Form.js
handleChange = event => {
const { name, value } = event.target
this.setState({
[name]: value,
})
}
Let's get this working before we move on to submitting the form.
In the render, let's get our two properties from state, and assign them as the values that correspond to the proper form keys.
We'll run the handleChange()
method as the onChange
of the input, and finally we'll export the Form
component.
src/Form.js
render() {
const { name, job } = this.state;
return (
<form>
<label htmlFor="name">Name</label>
<input type="text" name="name" id="name" value={name} onChange={this.handleChange} />
<label htmlFor="job">Job</label>
<input type="text" name="job" id="job" value={job} onChange={this.handleChange} />
</form>
);
}
export default Form;
In App.js
, we can render the form below the table.
src/App.js
return (
<div className="container">
<Table characterData={characters} removeCharacter={this.removeCharacter} />
<Form />
</div>
)
Now if we go to the front end of our app, we'll see a form that doesn't have a submit yet.
Update some fields and you'll see the local state of Form
being updated.
Cool.
Last step is to allow us to actually submit that data and update the parent state.
We'll create a function called handleSubmit()
on App
that will update the state by taking the existing this.state.characters
and adding the new character
parameter, using the ES6 spread operator.
src/App.js
handleSubmit = character => {
this.setState({ characters: [...this.state.characters, character] })
}
Let's make sure we pass that through as a parameter on Form
.
<Form handleSubmit={this.handleSubmit} />
Now in Form
, we'll create a method called submitForm()
that will call that function, and pass the Form
state through as the character
parameter we defined earlier.
It will also reset the state to the initial state, to clear the form after submit.
src/Form.js
submitForm = () => {
this.props.handleSubmit(this.state)
this.setState(this.initialState)
}
Finally, we'll add a submit button to submit the form.
We're using an onClick
instead of an onSubmit
since we're not using the standard submit functionality.
The click will call the submitForm
we just made.
<input type="button" value="Submit" onClick={this.submitForm} />
And that's it! The app is complete.
We can create, add, and remove users from our table.
Since the Table
and TableBody
were already pulling from the state, it will display properly.
If you got lost anywhere along the way, you can view the complete source on GitHub.
Pulling in API Data
One very common usage of React is pulling in data from an API.
If you're not familiar with what an API is or how to connect to one, I would recommend reading How to Connect to an API with JavaScript, which will walk you through what APIs are and how to use them with vanilla JavaScript.
As a little test, we can create a new Api.js
file, and create a new App
in there.
A public API we can test with is the Wikipedia API, and I have a URL endpoint right here for a random* search.
You can go to that link to see the API - and make sure you have JSONView installed on your browser.
We're going to use JavaScript's built-in Fetch to gather the data from that URL endpoint and display it.
You can switch between the app we created and this test file by just changing the URL in index.js
- import App from './Api';
.
I'm not going to explain this code line-by-line, as we've already learned about creating a component, rendering, and mapping through a state array.
The new aspect to this code is componentDidMount()
, a React lifecycle method.
Lifecycle is the order in which methods are called in React.
Mounting refers to an item being inserted into the DOM.
When we pull in API data, we want to use componentDidMount
, because we want to make sure the component has rendered to the DOM before we bring in the data.
In the below snippet, you'll see how we bring in data from the Wikipedia API, and display it on the page
Api.js
import React, { Component } from 'react'
class App extends Component {
state = {
data: [],
}
// Code is invoked after the component is mounted/inserted into the DOM tree.
componentDidMount() {
const url =
'https://en.wikipedia.org/w/api.php?action=opensearch&search=Seona+Dancing&format=json&origin=*'
fetch(url)
.then(result => result.json())
.then(result => { this.setState({ data: result, })
})
}
render() {
const { data } = this.state
const result = data.map((entry, index) => {
return <li key={index}>{entry}</li>
})
return <ul>{result}</ul>
}
}
export default App
Once you save and run this file in the local server, you'll see the Wikipedia API data displayed in the DOM.
There are other lifecycle methods, but going over them will be beyond the scope of this article.
You can read more about React components here.
*Wikipedia search choice may not be random.
It might be an article that I spearheaded back in 2005.
Building and Deploying a React App
Everything we've done so far has been in a development environment.
We've been compiling, hot-reloading, and updating on the fly.
For production, we're going to want to have static files loading in - none of the source code.
We can do this by making a build and deploying it.
Now, if you just want to compile all the React code and place it in the root of a directory somewhere, all you need to do is run the following line:
npm run build
This will create a build
folder which will contain your app.
Put the contents of that folder anywhere, and you're done!
We can also take it a step further, and have npm deploy for us.
We're going to build to GitHub pages, so you'll already have to be familiar with Git and getting your code up on GitHub.
Make sure you've exited out of your local React environment, so the code isn't currently running.
First, we're going to add a homepage
field to package.json
, that has the URL we want our app to live on.
package.json
"homepage": "https://taniarascia.github.io/react-tutorial",
We'll also add these two lines to the scripts
property.
"scripts": {
// ...
"predeploy": "npm run build",
"deploy": "gh-pages -d build"
}
In your project, you'll add gh-pages
to the devDependencies.
npm install --save-dev gh-pages
We'll create the build
, which will have all the compiled, static files.
npm run build
Finally, we'll deploy to gh-pages
.
npm run deploy
And we're done! The app is now available live at https://taniarascia.github.io/react-tutorial.
W3 React Tutorial
React is a JavaScript library for building user interfaces.
React is used to build single page applications.
React allows us to create reusable UI components.
Start learning React now »
Learning by Examples
Our "Show React" tool makes it easy to demonstrate React, it shows both the code and the result.
Example:
import React from 'react';
import ReactDOM from 'react-dom';
class Test extends React.Component {
render() {
return <h1>Hello World!</h1>;
}
}
ReactDOM.render(<Test />, document.getElementById('root'));
Run Example »
Create React App
In order to learn and test React, you should set up a React Environment on your computer.
This tutorial uses the create-react-app
.
The create-react-app
is an officially supported way to create React applications.
If you have NPM and Node.js installed, you can create a React application by first installing the create-react-app.
Install create-react-app by running this command in your terminal:
C:\Users\Your Name>npm install -g create-react-app
You are now ready to create your first React application!
Run this command to create a React application named
myfirstreact
:
C:\Users\Your Name>npx create-react-app myfirstreact
The create-react-app
will set up everything you need to run a React application.
Note: This tutorial uses
create-react-app
to demonstrate React examples. You will not be able to run the same examples on your computer if you do not install the create-react-app
environment.
Run the React Application
If you followed the two commands above, you are ready to run your first real React application!
Run this command to move to the myfirstreact
directory:
C:\Users\Your Name>cd myfirstreact
Run this command to execute the React application
myfirstreact
:
C:\Users\Your Name\myfirstreact>npm start
A new browser window will pop up with your newly created React App! If not, open your browser and type
localhost:3000
in the address bar.
What You Should Already Know
Before starting with React.JS, you should have intermediate experience in:
You should also have some experience with the new JavaScript features introduced in ECMAScript 6 (ES6), you will learn about them in the React ES6 chapter.
W3 React Introduction
What is React?
React is a JavaScript library created by Facebook.
React is a tool for building UI components.
How does React Work?
React creates a VIRTUAL DOM in memory.
Instead of manipulating the browser's DOM directly, React creates a virtual
DOM in memory, where it does all the necessary manipulating, before making the changes in the browser DOM.
React only changes what needs to be changed!
React finds out what changes have been made, and changes only
what needs to be changed.
You will learn the various aspects of how React does this in the rest of this tutorial.
React.JS History
Current version of React.JS is V16.8.6 (March 2019).
Initial Release to the Public (V0.3.0) was in July 2013.
React.JS was first used in 2011 for Facebook's Newsfeed feature.
Facebook Software Engineer, Jordan Walke, created it.
The create-react-app version 2.0 package was released in October 2018.
Create-react-app version 2.0 supports Babel 7, webpack 4, and Jest23.
W3 React Getting Started
To use React in production, you need NPM and Node.js
To get an overview of what React is, you can write React code directly in HTML.
But in order to use React in production, you need NPM and Node.js installed.
React Directly in HTML
The quickest way start learning React is to write React directly in your HTML files.
Start by including three scripts, the first two let us write React code in our
JavaScripts, and the third, Babel, allows us to write JSX
syntax and ES6 in older browsers.
Example
Include three CDN's in your HTML file:
<!DOCTYPE html>
<html>
<script src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
<body>
<div id="mydiv"></div>
<script type="text/babel">
class Hello extends React.Component {
render() {
return <h1>Hello World!</h1>
}
}
ReactDOM.render(<Hello />, document.getElementById('mydiv'))
</script>
</body>
</html>
Try it Yourself »
This way of using React can be OK for testing purposes, but for production you will need to set up a
React environment.
Setting up a React Environment
If you have NPM and Node.js installed, you can create a React application by first installing the create-react-app.
If you've already created the create-react-app you can skip this section.
Install create-react-app by running this command in your terminal:
C:\Users\Your Name>npm install -g create-react-app
Then you are able to create a React application, let's create one called myfirstreact
.
Run this command to create a React application named
myfirstreact
:
C:\Users\Your Name>npx create-react-app myfirstreact
The create-react-app will set up everything you need to run a React application.
Run the React Application
Now you are ready to run your first real React application!
Run this command to move to the myfirstreact
directory:
C:\Users\Your Name>cd myfirstreact
Run this command to run the React application
myfirstreact
:
C:\Users\Your Name\myfirstreact>npm start
A new browser window will pop up with your newly created React App! If not, open your browser and type
localhost:3000
in the address bar.
Modify the React Application
So far so good, but how do I change the content?
Look in the myfirstreact
directory, and you will find a
src
folder. Inside the
src
folder there is a file called
App.js
, open it and it will look like this:
/myfirstreact/src/App.js:
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
class App extends Component {
render() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
}
export default App;
Try changing the HTML content and save the file.
Notice that the changes is visible immediately after you save the file, you do not have to reload the browser!
Example
Replace all the content inside the <div className="App">
with a
<h1>
element.
See the changes in the browser when you click Save.
import React, { Component } from 'react';
class App extends Component {
render() {
return (
<div className="App">
<h1>Hello World!</h1>
</div>
);
}
}
export default App;
Notice that we have removed the imports we do not need (logo.svg and App.css).
What's Next?
Now you have a React Environment on your computer, and you are ready to learn more about React.
In the rest of this tutorial we will use our Show React tool to explain the various aspects of React, and how they are displayed in the browser.
If you want to follow the same steps on your computer, start by stripping down the src
folder to only contain two files: index.js
and
index.html
, in some builds you might find the index.html in the public folder instead, you should also remove any unnecessary lines of code inside the two files to make them look like the files in the Show React tool below:
Example
Click the "Run Example" button to see the result.
index.js
:
import React from 'react';
import ReactDOM from 'react-dom';
const myfirstelement = <h1>Hello React!</h1>
ReactDOM.render(myfirstelement, document.getElementById('root'));
index.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>React App</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
Run Example »
W3 React ES6
What is ES6?
ES6 stands for ECMAScript 6.
ECMAScript was created to standardize JavaScript, and ES6 is the 6th version of ECMAScript, it was published in 2015, and is also known as ECMAScript 2015.
Why Should I Learn ES6?
React uses ES6, and you should be familiar with some of the new features like:
- Classes
- Arrow Functions
- Variables (let, const, var)
Classes
ES6 introduced classes.
A class is a type of function, but instead of using the keyword
function
to initiate it, we use the keyword
class
, and the properties are assigned inside a
constructor()
method.
Example
A simple class constructor:
class Car {
constructor(name) {
this.brand = name;
}
}
Now you can create objects using the Car class:
Example
Create an object called "mycar" based on the Car class:
class Car {
constructor(name) {
this.brand = name;
}
}
mycar = new Car("Ford");
Try it Yourself »
Note: The constructor function is called automatically when the object is initialized.
Method in Classes
You can add your own methods in a class:
Example
Create a method named "present":
class Car {
constructor(name) {
this.brand = name;
}
present() {
return 'I have a ' + this.brand;
}
}
mycar = new Car("Ford");
mycar.present();
Try it Yourself »
As you can see in the example above, you call the method by referring to the object's method name followed by parentheses (parameters would go inside the parentheses).
Class Inheritance
To create a class inheritance, use the extends
keyword.
A class created with a class inheritance inherits all the methods from another class:
Example
Create a class named "Model" which will inherit the methods from the "Car"
class:
class Car {
constructor(name) {
this.brand = name;
}
present() {
return 'I have a ' + this.brand;
}
}
class Model extends Car {
constructor(name, mod) {
super(name);
this.model = mod;
}
show() {
return this.present() + ', it is a ' + this.model
}
}
mycar = new Model("Ford", "Mustang");
mycar.show();
Try it Yourself »
The super()
method refers to the parent class.
By calling the super()
method in the constructor method, we call the parent's constructor method and gets access to the parent's properties and methods.
Arrow Functions
Arrow functions were introduced in ES6.
Arrow functions allow us to write shorter function syntax:
Before:
hello = function() {
return "Hello World!";
}
Try it Yourself »
With Arrow Function:
hello = () => {
return "Hello World!";
}
Try it Yourself »
It gets shorter! If the function has only one statement, and the statement returns a value, you can remove the brackets and the
return
keyword:
Arrow Functions Return Value by Default:
hello = () => "Hello World!";
Try it Yourself »
Note: This works only if the function has only one statement.
If you have parameters, you pass them inside the parentheses:
Arrow Function With Parameters:
hello = (val) => "Hello " + val;
Try it Yourself »
In fact, if you have only one parameter, you can skip the parentheses as well:
Arrow Function Without Parentheses:
hello = val => "Hello " + val;
this
Try it Yourself »
What About this
?
The handling of this
is also different in arrow functions compared to regular functions.
In short, with arrow functions there are no binding of
this
.
In regular functions the this
keyword represented the object that called the function, which could be the window, the document, a button or whatever.
With arrow functions, the this
keyword always represents the object that defined the arrow function.
Let us take a look at two examples to understand the difference.
Both examples call a method twice, first when the page loads, and once again when the user clicks a button.
The first example uses a regular function, and the second example uses an arrow function.
The result shows that the first example returns two different objects (window and button),
and the second example returns the Header object twice.
Example
With a regular function, this
represents the object that called the function:
class Header {
constructor() {
this.color = "Red";
}
//Regular function:
changeColor = function() {
document.getElementById("demo").innerHTML += this;
}
}
myheader = new Header();
//The window object calls the function:
window.addEventListener("load", myheader.changeColor);
//A button object calls the function:
document.getElementById("btn").addEventListener("click", myheader.changeColor);
Try it Yourself »
Example
With an arrow function, this
represents the
Header object no matter who called the function:
class Header {
constructor() {
this.color = "Red";
}
//Arrow function:
changeColor = () => {
document.getElementById("demo").innerHTML += this;
}
}
myheader = new Header();
//The window object calls the function:
window.addEventListener("load", myheader.changeColor);
//A button object calls the function:
document.getElementById("btn").addEventListener("click", myheader.changeColor);
Try it Yourself »
Remember these differences when you are working with functions. Sometimes the behavior of regular functions is what you want, if not, use arrow functions.
Variables
Before ES6 there were only one way of defining your variables: with the
var
keyword. If you did not define them, they would be assigned to the global object. Unless you were in strict mode, then you would get an error if your variables were undefined.
Now, with ES6, there are three ways of defining your variables:
var
, let
, and const
.
var
var x = 5.6;
If you use var
outside of a function, it belongs to the global scope.
If you use var
inside of a function, it belongs to that function.
If you use var
inside of a block, i.e. a for loop, the variable is still available outside of that block.
var
has a function scope, not a
block scope.
let
let x = 5.6;
let
has a block scope.
let
is the block scoped version of
var
, and is limited to the block (or expression) where it is defined.
If you use let
inside of a block, i.e. a for loop, the variable is only available inside of that loop.
const
const x = 5.6;
const
is a variable that once it has been created, its value can never change.
const
has a block scope.
W3 React Render HTML
React's goal is in many ways to render HTML in a web page.
React renders HTML to the web page by using a function called
ReactDOM.render()
.
The Render Function
The ReactDOM.render()
function takes two arguments, HTML code and an HTML element.
The purpose of the function is to display the specified HTML code inside the specified HTML element.
Example
Display a paragraph inside the "root" element:
ReactDOM.render(<p>Hello</p>, document.getElementById('root'));
The result is displayed in the <div id="root">
element:
<body>
<div id="root"></div>
</body>
Run Example »
The HTML Code
The HTML code in this tutorial uses JSX which allows you to write HTML tags inside the JavaScript code:
Do not worry if the syntax is unfamiliar, you will learn more about JSX in the next chapter.
Example
Create a variable that contains HTML code and display it in the root node:
const myelement = (
<table>
<tr>
<th>Name</th>
</tr>
<tr>
<td>John</td>
</tr>
<tr>
<td>Elsa</td>
</tr>
</table>
);
ReactDOM.render(myelement, document.getElementById('root'));
Run Example »
The Root Node
The root node is the HTML element where you want to display the result.
It is like a container for content managed by React.
It does NOT have to be a <div>
element and it does
NOT have to have the id='root'
:
Example
The root node can be called whatever you like:
<body>
<header id="sandy"></header>
</body>
Display the result in the <header id="sandy">
element:
ReactDOM.render(<p>Hallo</p>, document.getElementById('sandy'));
Run Example »
W3 React JSX
What is JSX?
JSX stands for JavaScript XML.
JSX allows us to write HTML in React.
JSX makes it easier to write and add HTML in React.
Coding JSX
JSX allows us to write HTML elements in JavaScript and place them in the DOM
without any createElement()
and/or
appendChild()
methods.
JSX converts HTML tags into react elements.
You are not required to use JSX, but JSX makes it easier to write React applications.
Let us demonstrate with two examples, the first uses JSX and the second does not:
Example 1
JSX:
const myelement = <h2>I Love JSX!</h2>;
ReactDOM.render(myelement, document.getElementById('root'));
Run Example »
Example 2
Without JSX:
const myelement = React.createElement('h1', {}, 'I do not use JSX!');
ReactDOM.render(myelement, document.getElementById('root'));
Run Example »
As you can see in the first example, JSX allows us to write HTML directly within the JavaScript code.
JSX is an extension of the JavaScript language based on ES6, and is translated into regular JavaScript at runtime.
Expressions in JSX
With JSX you can write expressions inside curly braces { }
.
The expression can be a React variable, or property, or any other valid JavaScript expression. JSX will execute the expression and return the result:
Example
Execute the expression 5 + 5
:
const myelement = <h2>React is {5 + 5} times better with JSX</h2>;
Run Example »
Inserting a Large Block of HTML
To write HTML on multiple lines, put the HTML inside parentheses:
Example
Create a list with three list items:
const myelement = (
<ul>
<li>Apples</li>
<li>Bananas</li>
<li>Cherries</li>
</ul>
);
Run Example »
One Top Level Element
The HTML code must be wrapped in ONE top level element.
So if you like to write two headers, you must put them inside a parent element, like a div
element
Example
Wrap two headers inside one DIV element:
const myelement = (
<div>
<h1>I am a Header.</h1>
<h1>I am a Header too.</h1>
</div>
);
Run Example »
JSX will throw an error if the HTML is not correct, or if the HTML misses a parent element.
Elements Must be Closed
JSX follows XML rules, and therefore HTML elements must be properly closed.
Example
Close empty elements with />
const myelement = <input type="text" />;
Run Example »
JSX will throw an error if the HTML is not properly closed.
W3 React Components
Components are like functions that return HTML elements.
React Components
Components are independent and reusable bits of code.
They serve the same purpose as JavaScript functions,
but work in isolation and return HTML via a render() function.
Components come in two types, Class components and Function components, in this tutorial we will concentrate on Class components.
Create a Class Component
When creating a React component, the component's name must start with an upper case letter.
The component has to include the extends React.Component
statement, this statement creates an inheritance to
React.Component, and gives your component access to React.Component's functions.
The component also requires a render()
method,
this method returns HTML.
Example
Create a Class component called Car
class Car extends React.Component {
render() {
return <h2>Hi, I am a Car!</h2>;
}
}
Now your React application has a component called Car, which returns a
<h2>
element.
To use this component in your application, use similar syntax as normal HTML:
<Car />
Example
Display the Car
component in the "root" element:
ReactDOM.render(<Car />, document.getElementById('root'));
Run Example »
Create a Function Component
Here is the same example as above, but created using a Function component instead.
A Function component also returns HTML, and behaves pretty much the same way as a Class component, but Class components have some additions, and will be preferred in this tutorial.
Example
Create a Function component called Car
function Car() {
return <h2>Hi, I am also a Car!</h2>;
}
Once again your React application has a Car component.
Refer to the Car component as normal HTML
(except in React, components must start with an upper case letter):
Example
Display the Car
component in the "root" element:
ReactDOM.render(<Car />, document.getElementById('root'));
Run Example »
Component Constructor
If there is a constructor()
function in your component, this function will be called when the component gets initiated.
The constructor function is where you initiate the component's properties.
In React, component properties should be kept in an object called
state
.
The constructor function is also where you honor the inheritance of the parent component by including the super()
statement, which executes the parent component's constructor function, and your component has access to all the functions of the parent component (React.Component
).
Example
Create a constructor function in the Car component, and add a color property:
class Car extends React.Component {
constructor() {
super();
this.state = {color: "red"};
}
render() {
return <h2>I am a Car!</h2>;
}
}
Use the color property in the render() function:
Example
class Car extends React.Component {
constructor() {
super();
this.state = {color: "red"};
}
render() {
return <h2>I am a {this.state.color} Car!</h2>;
}
}
Run Example »
Props
Another way of handling component properties is by using props
.
Props are like function arguments, and you send them into the component as attributes.
Example
Use an attribute to pass a color to the Car component, and use it in the render() function:
class Car extends React.Component {
render() {
return <h2>I am a {this.props.color} Car!</h2>;
}
}
ReactDOM.render(<Car color="red"/>, document.getElementById('root'));
Run Example »
Components in Components
We can refer to components inside other components:
Example
Use the Car component inside the Garage component:
class Car extends React.Component {
render() {
return <h2>I am a Car!</h2>;
}
}
class Garage extends React.Component {
render() {
return (
<div>
<h1>Who lives in my Garage?</h1>
<Car />
</div>
);
}
}
ReactDOM.render(<Garage />, document.getElementById('root'));
Run Example »
Components in Files
React is all about re-using code, and it can be smart to insert some of your components in separate files.
To do that, create a new file with a .js
file extension and put the code inside it:
Note that the file must start by importing React (as before), and it has to end with the statement export default Car;
.
Example
This is the new file, we named it "App.js":
import React from 'react';
import ReactDOM from 'react-dom';
class Car extends React.Component {
render() {
return <h2>Hi, I am a Car!</h2>;
}
}
export default Car;
To be able to use the Car component, you have to import the file in your application.
Example
Now we import the "App.js" file in the application, and we can use the Car component as if it was created here.
import React from 'react';
import ReactDOM from 'react-dom';
import Car from './App.js';
ReactDOM.render(<Car />, document.getElementById('root'));
Run Example »
W3 React Props
Props are arguments passed into React components.
Props are passed to components via HTML attributes.
React Props
React Props are like function arguments in JavaScript and attributes in HTML.
To send props into a component, use the same syntax as HTML attributes:
Example
Add a "brand" attribute to the Car element:
const myelement = <Car brand="Ford" />;
The component receives the argument as a props
object:
Example
Use the brand attribute in the component:
class Car extends React.Component {
render() {
return <h2>I am a {this.props.brand}!</h2>;
}
}
Run Example »
Pass Data
Props are also how you pass data from one component to another, as parameters.
Example
Send the "brand" property from the Garage component to the Car component:
class Car extends React.Component {
render() {
return <h2>I am a {this.props.brand}!</h2>;
}
}
class Garage extends React.Component {
render() {
return (
<div>
<h1>Who lives in my garage?</h1>
<Car brand="Ford" />
</div>
);
}
}
ReactDOM.render(<Garage />, document.getElementById('root'));
Run Example »
If you have a variable to send, and not a string as in the example above, you just put the variable name inside curly brackets:
Example
Create a variable named "carname" and send it to the Car component:
class Car extends React.Component {
render() {
return <h2>I am a {this.props.brand}!</h2>;
}
}
class Garage extends React.Component {
render() {
const carname = "Ford";
return (
<div>
<h1>Who lives in my garage?</h1>
<Car brand={carname} />
</div>
);
}
}
ReactDOM.render(<Garage />, document.getElementById('root'));
Run Example »
Or if it was an object:
Example
Create an object named "carinfo" and send it to the Car component:
class Car extends React.Component {
render() {
return <h2>I am a {this.props.brand.model}!</h2>;
}
}
class Garage extends React.Component {
render() {
const carinfo = {name: "Ford", model: "Mustang"};
return (
<div>
<h1>Who lives in my garage?</h1>
<Car brand={carinfo} />
</div>
);
}
}
ReactDOM.render(<Garage />, document.getElementById('root'));
Run Example »
Props in the Constructor
If your component has a constructor function, the props should always be passed to the constructor and also to the React.Component via the
super()
method.
Example
class Car extends React.Component {
constructor(props) {
super(props);
}
render() {
return <h2>I am a {this.props.model}!</h2>;
}
}
ReactDOM.render(<Car model="Mustang"/>, document.getElementById('root'));
Note: React Props are read-only! You will get an error if you try to change their value.
W3 React State
React components has a built-in state
object.
The state
object is where you store property values that belongs to the component.
When the state
object changes,
the component re-renders.
Creating the state
Object
The state
object is initialized in the constructor:
Example:
Specify the state
object in the constructor method:
class Car extends React.Component {
constructor(props) {
super(props);
this.state = {brand: "Ford"};
}
render() {
return (
<div>
<h1>My Car</h1>
</div>
);
}
}
The state
object can contain as many properties as you like:
Example:
Specify all the properties your component need:
class Car extends React.Component {
constructor(props) {
super(props);
this.state = {
brand: "Ford",
model: "Mustang",
color: "red",
year: 1964
};
}
render() {
return (
<div>
<h1>My Car</h1>
</div>
);
}
}
Using the state
Object
Refer to the state
object anywhere in the component by using the
this.state.propertyname
syntax:
Example:
Refer to the state
object in the
render()
method:
class Car extends React.Component {
constructor(props) {
super(props);
this.state = {
brand: "Ford",
model: "Mustang",
color: "red",
year: 1964
};
}
render() {
return (
<div>
<h1>My {this.state.brand}</h1>
<p>
It is a {this.state.color}
{this.state.model}
from {this.state.year}.
</p>
</div>
);
}
}
Run Example »
Changing the state
Object
To change a value in the state object, use the this.setState()
method.
When a value in the state
object changes,
the component will re-render, meaning that the output will change according to the new value(s).
Example:
Add a button with an onClick
event that
will change the color property:
class Car extends React.Component {
constructor(props) {
super(props);
this.state = {
brand: "Ford",
model: "Mustang",
color: "red",
year: 1964
};
}
changeColor = () => {
this.setState({color: "blue"});
}
render() {
return (
<div>
<h1>My {this.state.brand}</h1>
<p>
It is a {this.state.color}
{this.state.model}
from {this.state.year}.
</p>
<button
type="button"
onClick={this.changeColor}
>Change color</button>
</div>
);
}
}
Run Example »
Always use the setState()
method to change the state object,
it will ensure that the component knows its been updated and calls the render() method
(and all the other lifecycle methods).
W3 React Lifecycle
Lifecycle of Components
Each component in React has a lifecycle which you can monitor and manipulate during its three main phases.
The three phases are: Mounting, Updating, and
Unmounting.
Mounting
Mounting means putting elements into the DOM.
React has four built-in methods that gets called, in this order, when mounting a component:
constructor()
getDerivedStateFromProps()
render()
componentDidMount()
The render()
method is required and will always be called, the others are optional and will be called if you define them.
constructor
The constructor()
method is called before anything else,
when the component is initiated, and it is the natural place to set up the initial state
and other initial values.
The constructor()
method is called with the
props
, as arguments, and you should always start by calling the super(props)
before anything else, this will initiate the parent's constructor method and allows the component to inherit methods from its parent (React.Component
).
Example:
The constructor
method is called, by
React, every time you make a component:
class Header extends React.Component {
constructor(props) {
super(props);
this.state = {favoritecolor: "red"};
}
render() {
return (
<h1>My Favorite Color is {this.state.favoritecolor}</h1>
);
}
}
ReactDOM.render(<Header />, document.getElementById('root'));
Run Example »
getDerivedStateFromProps
The getDerivedStateFromProps()
method is called right before rendering the element(s) in the DOM.
This is the natural place to set the state
object based on the initial
props
.
It takes
state
as an argument, and returns an object with changes to the
state
.The example below starts with the favorite color being
"red", but the
getDerivedStateFromProps()
method updates the favorite color based on the
favcol
attribute:
Example:
The getDerivedStateFromProps
method is called
right before the render method:
class Header extends React.Component {
constructor(props) {
super(props);
this.state = {favoritecolor: "red"};
}
static getDerivedStateFromProps(props, state) {
return {favoritecolor: props.favcol };
}
render() {
return (
<h1>My Favorite Color is {this.state.favoritecolor}</h1>
);
}
}
ReactDOM.render(<Header favcol="yellow"/>, document.getElementById('root'));
Run Example »
render
The render()
method is required, and is the method that actually outputs the HTML to the DOM.
Example:
A simple component with a simple render()
method:
class Header extends React.Component {
render() {
return (
<h1>This is the content of the Header component</h1>
);
}
}
ReactDOM.render(<Header />, document.getElementById('root'));
Run Example »
componentDidMount
The componentDidMount()
method is called after the component is rendered.
This is where you run statements that requires that the component is already placed in the DOM.
Example:
At first my favorite color is red, but give me a second, and it is yellow
instead:
class Header extends React.Component {
constructor(props) {
super(props);
this.state = {favoritecolor: "red"};
}
componentDidMount() {
setTimeout(() => {
this.setState({favoritecolor: "yellow"})
}, 1000)
}
render() {
return (
<h1>My Favorite Color is {this.state.favoritecolor}</h1>
);
}
}
ReactDOM.render(<Header />, document.getElementById('root'));
Run Example »
Updating
The next phase in the lifecycle is when a component is updated.
A component is updated whenever there is a change in the component's
state
or props
.
React has five built-in methods that gets called, in this order, when a component is updated:
getDerivedStateFromProps()
shouldComponentUpdate()
render()
getSnapshotBeforeUpdate()
componentDidUpdate()
The render()
method is required and will always be called, the others are optional and will be called if you define them.
getDerivedStateFromProps
Also at updates the getDerivedStateFromProps
method is called. This is the first method that is called when a component gets updated.
This is still the natural place to set the state
object based on the initial props.
The example below has a button that changes the favorite color to blue, but since the getDerivedStateFromProps()
method is called,
which updates the state with the color from the favcol attribute, the favorite color is still rendered as yellow:
Example:
If the component gets updated, the getDerivedStateFromProps()
method is called:
class Header extends React.Component {
constructor(props) {
super(props);
this.state = {favoritecolor: "red"};
}
static getDerivedStateFromProps(props, state) {
return {favoritecolor: props.favcol };
}
changeColor = () => {
this.setState({favoritecolor: "blue"});
}
render() {
return (
<div>
<h1>My Favorite Color is {this.state.favoritecolor}</h1>
<button type="button" onClick={this.changeColor}>Change color</button>
</div>
);
}
}
ReactDOM.render(<Header favcol="yellow"/>, document.getElementById('root'));
Run Example »
shouldComponentUpdate
In the shouldComponentUpdate()
method
you can return a Boolean value that specifies whether React should continue with the rendering or not.
The default value is true
.
The example below shows what happens when the
shouldComponentUpdate()
method returns false
:
Example:
Stop the component from rendering at any update:
class Header extends React.Component {
constructor(props) {
super(props);
this.state = {favoritecolor: "red"};
}
shouldComponentUpdate() {
return false;
}
changeColor = () => {
this.setState({favoritecolor: "blue"});
}
render() {
return (
<div>
<h1>My Favorite Color is {this.state.favoritecolor}</h1>
<button type="button" onClick={this.changeColor}>Change color</button>
</div>
);
}
}
ReactDOM.render(<Header />, document.getElementById('root'));
Run Example »
Example:
Same example as above, but this time the shouldComponentUpdate()
method returns
true
instead:
class Header extends React.Component {
constructor(props) {
super(props);
this.state = {favoritecolor: "red"};
}
shouldComponentUpdate() {
return true;
}
changeColor = () => {
this.setState({favoritecolor: "blue"});
}
render() {
return (
<div>
<h1>My Favorite Color is {this.state.favoritecolor}</h1>
<button type="button" onClick={this.changeColor}>Change color</button>
</div>
);
}
}
ReactDOM.render(<Header />, document.getElementById('root'));
Run Example »
render
The render()
method is of course called when a component gets updated,
it has to re-render the HTML to the DOM, with the new changes.
The example below has a button that changes the favorite color to blue:
Example:
Click the button to make a change in the component's state:
class Header extends React.Component {
constructor(props) {
super(props);
this.state = {favoritecolor: "red"};
}
changeColor = () => {
this.setState({favoritecolor: "blue"});
}
render() {
return (
<div>
<h1>My Favorite Color is {this.state.favoritecolor}</h1>
<button type="button" onClick={this.changeColor}>Change color</button>
</div>
);
}
}
ReactDOM.render(<Header />, document.getElementById('root'));
Run Example »
getSnapshotBeforeUpdate
In the getSnapshotBeforeUpdate()
method
you have access to the props
and
state
before the update, meaning that even after the update, you can check what the values were before the update.
If the getSnapshotBeforeUpdate()
method
is present, you should also include the
componentDidUpdate()
method, otherwise you will get an error.
The example below might seem complicated, but all it does is this:
When the component is mounting it is rendered with the favorite color "red".
When the component has been mounted, a timer changes the state, and after one second, the favorite color becomes "yellow".
This action triggers the update phase, and since this component has a
getSnapshotBeforeUpdate()
method, this method is executed, and writes a message to the empty DIV1 element.
Then the componentDidUpdate()
method is executed and writes a message in the empty DIV2 element:
Example:
Use the
getSnapshotBeforeUpdate()
method to find out
what the state
object looked like before
the update:
class Header extends React.Component {
constructor(props) {
super(props);
this.state = {favoritecolor: "red"};
}
componentDidMount() {
setTimeout(() => {
this.setState({favoritecolor: "yellow"})
}, 1000)
}
getSnapshotBeforeUpdate(prevProps, prevState) {
document.getElementById("div1").innerHTML =
"Before the update, the favorite was " + prevState.favoritecolor;
}
componentDidUpdate() {
document.getElementById("div2").innerHTML =
"The updated favorite is " + this.state.favoritecolor;
}
render() {
return (
<div>
<h1>My Favorite Color is {this.state.favoritecolor}</h1>
<div id="div1"></div>
<div id="div2"></div>
</div>
);
}
}
ReactDOM.render(<Header />, document.getElementById('root'));
Run Example »
componentDidUpdate
The componentDidUpdate
method
is called after the component is updated in the DOM.
The example below might seem complicated, but all it does is this:
When the component is mounting it is rendered with the favorite color "red".
When the component has been mounted, a timer changes the state, and the color becomes "yellow".
This action triggers the update phase, and since this component has a componentDidUpdate
method, this method is executed and writes a message in the empty DIV element:
Example:
The componentDidUpdate
method is called
after the update has been rendered in the DOM:
class Header extends React.Component {
constructor(props) {
super(props);
this.state = {favoritecolor: "red"};
}
componentDidMount() {
setTimeout(() => {
this.setState({favoritecolor: "yellow"})
}, 1000)
}
componentDidUpdate() {
document.getElementById("mydiv").innerHTML =
"The updated favorite is " + this.state.favoritecolor;
}
render() {
return (
<div>
<h1>My Favorite Color is {this.state.favoritecolor}</h1>
<div id="mydiv"></div>
</div>
);
}
}
ReactDOM.render(<Header />, document.getElementById('root'));
Run Example »
Unmounting
The next phase in the lifecycle is when a component is removed from the DOM, or unmounting as React likes to call it.
React has only one built-in method that gets called when a component is unmounted:
componentWillUnmount
The componentWillUnmount
method is called when the component is about to be removed from the DOM.
Example:
Click the button to delete the header:
class Container extends React.Component {
constructor(props) {
super(props);
this.state = {show: true};
}
delHeader = () => {
this.setState({show: false});
}
render() {
let myheader;
if (this.state.show) {
myheader = <Child />;
};
return (
<div>
{myheader}
<button type="button" onClick={this.delHeader}>Delete Header</button>
</div>
);
}
}
class Child extends React.Component {
componentWillUnmount() {
alert("The component named Header is about to be unmounted.");
}
render() {
return (
<h1>Hello World!</h1>
);
}
}
ReactDOM.render(<Container />, document.getElementById('root'));
Run Example »
W3 React Events
Just like HTML, React can perform actions based on user events.
React has the same events as HTML: click, change, mouseover etc.
Adding Events
React events are written in camelCase syntax:
onClick
instead of onclick
.
React event handlers are written inside curly braces:
onClick={shoot}
instead of
onClick="shoot()"
.
React:
<button onClick={shoot}>Take the Shot!</button>
Run Example »
HTML:
<button onclick="shoot()">Take the Shot!</button>
Event Handlers
A good practice is to put the event handler as a method in the component class:
Example:
Put the shoot
function inside the
Football
component:
class Football extends React.Component {
shoot() {
alert("Great Shot!");
}
render() {
return (
<button onClick={this.shoot}>Take the shot!</button>
);
}
}
ReactDOM.render(<Football />, document.getElementById('root'));
Run Example »
Bind this
For methods in React, the this
keyword should represent the component that owns the method.
That is why you should use arrow functions. With arrow functions,
this
will always represent the object that defined the arrow function.
Example:
class Football extends React.Component {
shoot = () => {
alert(this);
/*
The 'this' keyword refers to the component object
*/
}
render() {
return (
<button onClick={this.shoot}>Take the shot!</button>
);
}
}
ReactDOM.render(<Football />, document.getElementById('root'));
Run Example »
Why Arrow Functions?
In class components, the this
keyword is not defined by default,
so with regular functions the this
keyword represents the object that called the method, which can be the global window object, a HTML button, or whatever.
If you must use regular functions instead of arrow functions you have to bind
this
to the component instance using the
bind()
method:
Example:
Make this
available in the
shoot
function by binding it in the
constructor
function:
class Football extends React.Component {
constructor(props) {
super(props)
this.shoot = this.shoot.bind(this)
}
shoot() {
alert(this);
/*
Thanks to the binding in the constructor function,
the 'this' keyword now refers to the component object
*/
}
render() {
return (
<button onClick={this.shoot}>Take the shot!</button>
);
}
}
ReactDOM.render(<Football />, document.getElementById('root'));
Run Example »
Without the binding, the this
keyword would return undefined
.
Passing Arguments
If you want to send parameters into an event handler, you have two options:
1. Make an anonymous arrow function:
Example:
Send "Goal" as a parameter to the shoot
function, using arrow
function:
class Football extends React.Component {
shoot = (a) => {
alert(a);
}
render() {
return (
<button onClick={() => this.shoot("Goal")}>Take the shot!</button>
);
}
}
ReactDOM.render(<Football />, document.getElementById('root'));
Run Example »
Or:
2. Bind the event handler to this
.
Note that the first argument has to be this
.
Example:
Send "Goal" as a parameter to the shoot
function:
class Football extends React.Component {
shoot(a) {
alert(a);
}
render() {
return (
<button onClick={this.shoot.bind(this, "Goal")}>Take the shot!</button>
);
}
}
ReactDOM.render(<Football />, document.getElementById('root'));
Run Example »
Note on the second example: If you send arguments without using the bind
method,
(this.shoot(this, "Goal")
instead of
this.shoot.bind(this, "Goal")
), the
shoot
function will be executed when the page is loaded instead of waiting for the button to be clicked.
React Event Object
Event handlers have access to the React event that triggered the function.
In our example the event is the "click" event. Notice that once again the syntax is different when using arrow functions or not.
With the arrow function you have to send the event argument manually:
Example:
Arrow Function: Sending the event object manually:
class Football extends React.Component {
shoot = (a, b) => {
alert(b.type);
/*
'b' represents the React event that triggered the function,
in this case the 'click' event
*/
}
render() {
return (
<button onClick={(ev) => this.shoot("Goal", ev)}>Take the shot!</button>
);
}
}
ReactDOM.render(<Football />, document.getElementById('root'));
Run Example »
Without arrow function, the React event object is sent automatically as the last argument when using the bind()
method:
Example:
With the bind()
method, the event object
is sent as the last argument:
class Football extends React.Component {
shoot = (a, b) => {
alert(b.type);
/*
'b' represents the React event that triggered the function,
in this case the 'click' event
*/
}
render() {
return (
<button onClick={this.shoot.bind(this, "Goal")}>Take the shot!</button>
);
}
}
ReactDOM.render(<Football />, document.getElementById('root'));
Run Example »
W3 React Forms
Just like in HTML, React uses forms to allow users to interact with the web page.
Adding Forms in React
You add a form with React like any other element:
Example:
Add a form that allows users to enter their name:
class MyForm extends React.Component {
render() {
return (
<form>
<h1>Hello</h1>
<p>Enter your name:</p>
<input
type="text"
/>
</form>
);
}
}
ReactDOM.render(<MyForm />, document.getElementById('root'));
Run Example »
Handling Forms
Handling forms is about how you handle the data when it changes value or gets submitted.
In HTML, form data is usually handled by the DOM.
In React, form data is usually handled by the components.
When the data is handled by the components, all the data is stored in the component
state
.
You can control changes by adding event handlers in the
onChange
attribute:
Example:
Add an event handler in the onChange
attribute, and let the event handler update the
state
object:
class MyForm extends React.Component {
constructor(props) {
super(props);
this.state = { username: '' };
}
myChangeHandler = (event) => {
this.setState({username: event.target.value});
}
render() {
return (
<form>
<h1>Hello {this.state.username}</h1>
<p>Enter your name:</p>
<input
type='text'
onChange={this.myChangeHandler}
/>
</form>
);
}
}
ReactDOM.render(<MyForm />, document.getElementById('root'));
Run Example »
Note: You must initialize the state
in the constructor method before you can use it.
Note: You get access to the field value by using the event.target.value
syntax.
Conditional Rendering
If you do not want to display the h1 element until the user has done any input, you can add an if statement.
Look at the example below and note the following:
1. We create an empty variable, in this example we call it
header
.
2. We add an if statement to insert content to the
header
variable if the user has done any input.
3. We insert the header
variable in the output, using curly brackets.
Example:
Display the header only if username is defined:
class MyForm extends React.Component {
constructor(props) {
super(props);
this.state = { username: '' };
}
myChangeHandler = (event) => {
this.setState({username: event.target.value});
}
render() {
let header = '';
if (this.state.username) {
header = <h1>Hello {this.state.username}</h1>;
} else {
header = '';
}
return (
<form>
{header}
<p>Enter your name:</p>
<input
type='text'
onChange={this.myChangeHandler}
/>
</form>
);
}
}
ReactDOM.render(<MyForm />, document.getElementById('root'));
Run Example »
Submitting Forms
You can control the submit action by adding an event handler in the onSubmit attribute:
Example:
Add a submit button and an event handler in the onSubmit
attribute:
class MyForm extends React.Component {
constructor(props) {
super(props);
this.state = { username: '' };
}
mySubmitHandler = (event) => {
event.preventDefault();
alert("You are submitting " + this.state.username);
}
myChangeHandler = (event) => {
this.setState({username: event.target.value});
}
render() {
return (
<form onSubmit={this.mySubmitHandler}>
<h1>Hello {this.state.username}</h1>
<p>Enter your name, and submit:</p>
<input
type='text'
onChange={this.myChangeHandler}
/>
<input
type='submit'
/>
</form>
);
}
}
ReactDOM.render(<MyForm />, document.getElementById('root'));
Run Example »
Note that we use event.preventDefault()
to prevent the form from actually being submitted.
Multiple Input Fields
You can control the values of more than one input field by adding a
name
attribute to each element.
When you initialize the state in the constructor, use the field names.
To access the fields in the event handler use the
event.target.name
and
event.target.value
syntax.
To update the state in the this.setState
method, use square brackets [bracket notation] around the property name.
Example:
Write a form with two input fields:
class MyForm extends React.Component {
constructor(props) {
super(props);
this.state = {
username: '',
age: null,
};
}
myChangeHandler = (event) => {
let nam = event.target.name;
let val = event.target.value;
this.setState({[nam]: val});
}
render() {
return (
<form>
<h1>Hello {this.state.username} {this.state.age}</h1>
<p>Enter your name:</p>
<input
type='text'
name='username'
onChange={this.myChangeHandler}
/>
<p>Enter your age:</p>
<input
type='text'
name='age'
onChange={this.myChangeHandler}
/>
</form>
);
}
}
ReactDOM.render(<MyForm />, document.getElementById('root'));
Run Example »
Note: We use the same event handler function for both input fields,
we could write one event handler for each, but this gives us much cleaner code and is the preferred way in React.
Validating Form Input
You can validate form input when the user is typing or you can wait until the form gets submitted.
Example:
When you fill in your age, you will get an alert if the age field is not numeric:
class MyForm extends React.Component {
constructor(props) {
super(props);
this.state = {
username: '',
age: null,
};
}
myChangeHandler = (event) => {
let nam = event.target.name;
let val = event.target.value;
if (nam === "age") {
if (!Number(val)) {
alert("Your age must be a number");
}
}
this.setState({[nam]: val});
}
render() {
return (
<form>
<h1>Hello {this.state.username} {this.state.age}</h1>
<p>Enter your name:</p>
<input
type='text'
name='username'
onChange={this.myChangeHandler}
/>
<p>Enter your age:</p>
<input
type='text'
name='age'
onChange={this.myChangeHandler}
/>
</form>
);
}
}
ReactDOM.render(<MyForm />, document.getElementById('root'));
Run Example »
Below you will see the same example as above,
but the validation is done when the form gets submitted instead of when you write in the field.
Example:
Same example, but with the validation at form submit:
class MyForm extends React.Component {
constructor(props) {
super(props);
this.state = {
username: '',
age: null,
};
}
mySubmitHandler = (event) => {
event.preventDefault();
let age = this.state.age;
if (!Number(age)) {
alert("Your age must be a number");
}
}
myChangeHandler = (event) => {
let nam = event.target.name;
let val = event.target.value;
this.setState({[nam]: val});
}
render() {
return (
<form onSubmit={this.mySubmitHandler}>
<h1>Hello {this.state.username} {this.state.age}</h1>
<p>Enter your name:</p>
<input
type='text'
name='username'
onChange={this.myChangeHandler}
/>
<p>Enter your age:</p>
<input
type='text'
name='age'
onChange={this.myChangeHandler}
/>
<br/>
<br/>
<input type='submit' />
</form>
);
}
}
ReactDOM.render(<MyForm />, document.getElementById('root'));
Run Example »
Adding Error Message
Error messages in alert boxes can be annoying, so let's make an error message that is empty by default, but displays the error when the user inputs anything invalid:
Example:
When you fill in your age as not numeric, an error message is displayed:
class MyForm extends React.Component {
constructor(props) {
super(props);
this.state = {
username: '',
age: null,
errormessage: ''
};
}
myChangeHandler = (event) => {
let nam = event.target.name;
let val = event.target.value;
let err = '';
if (nam === "age") {
if (val !="" && !Number(val)) {
err = <strong>Your age must be a number</strong>;
}
}
this.setState({errormessage: err});
this.setState({[nam]: val});
}
render() {
return (
<form>
<h1>Hello {this.state.username} {this.state.age}</h1>
<p>Enter your name:</p>
<input
type='text'
name='username'
onChange={this.myChangeHandler}
/>
<p>Enter your age:</p>
<input
type='text'
name='age'
onChange={this.myChangeHandler}
/>
{this.state.errormessage}
</form>
);
}
}
ReactDOM.render(<MyForm />, document.getElementById('root'));
Run Example »
Textarea
The textarea element in React is slightly different from ordinary HTML.
In HTML the value of a textarea was the text between the start tag
<textarea>
and the end tag </textarea>
, in React the value of a textarea is placed in a value attribute:
Example:
A simple textarea with some content initialized in the constructor:
class MyForm extends React.Component {
constructor(props) {
super(props);
this.state = {
description: 'The content of a textarea goes in the value attribute'
};
}
render() {
return (
<form>
<textarea value={this.state.description} />
</form>
);
}
}
ReactDOM.render(<MyForm />, document.getElementById('root'));
Run Example »
Select
A drop down list, or a select box, in React is also a bit different from HTML.
in HTML, the selected value in the drop down list was defined with the selected
attribute:
HTML:
<select>
<option value="Ford">Ford</option>
<option value="Volvo" selected>Volvo</option>
<option value="Fiat">Fiat</option>
</select>
In React, the selected value is defined with a value
attribute on the select
tag:
Example:
A simple select box, where the selected value "Volvo" is initialized in the constructor:
class MyForm extends React.Component {
constructor(props) {
super(props);
this.state = {
mycar: 'Volvo'
};
}
render() {
return (
<form>
<select value={this.state.mycar}>
<option value="Ford">Ford</option>
<option value="Volvo">Volvo</option>
<option value="Fiat">Fiat</option>
</select>
</form>
);
}
}
ReactDOM.render(<MyForm />, document.getElementById('root'));
Run Example »
W3 Styling React Using CSS
There are many ways to style React with CSS, this tutorial will take a closer look at inline styling, and CSS
stylesheet.
Inline Styling
To style an element with the inline style attribute, the value must be a
JavaScript object:
Example:
Insert an object with the styling information:
class MyHeader extends React.Component {
render() {
return (
<div>
<h1 style={{color: "red"}}>Hello Style!</h1>
<p>Add a little style!</p>
</div>
);
}
}
Run Example »
Note: In JSX, JavaScript expressions are written inside curly braces,
and since JavaScript objects also use curly braces,
the styling in the example above is written inside two sets of curly braces {{}}
.
camelCased Property Names
Since the inline CSS is written in a JavaScript object, properties with two names, like background-color
,
must be written with camel case syntax:
Example:
Use backgroundColor
instead of
background-color
:
class MyHeader extends React.Component {
render() {
return (
<div>
<h1 style={{backgroundColor: "lightblue"}}>Hello Style!</h1>
<p>Add a little style!</p>
</div>
);
}
}
Run Example »
JavaScript Object
You can also create an object with styling information, and refer to it in the style attribute:
Example:
Create a style object named mystyle
:
class MyHeader extends React.Component {
render() {
const mystyle = {
color: "white",
backgroundColor: "DodgerBlue",
padding: "10px",
fontFamily: "Arial"
};
return (
<div>
<h1 style={mystyle}>Hello Style!</h1>
<p>Add a little style!</p>
</div>
);
}
}
Run Example »
CSS Stylesheet
You can write your CSS styling in a separate file, just save the file with the
.css
file extension, and import it in your application.
App.css:
Create a new file called "App.css" and insert some CSS code in it:
body {
background-color: #282c34;
color: white;
padding: 40px;
font-family: Arial;
text-align: center;
}
Note: You can call the file whatever you like, just remember the correct file extension.
Import the stylesheet in your application:
index.js:
import React from 'react';
import ReactDOM from 'react-dom';
import './App.css';
class MyHeader extends React.Component {
render() {
return (
<div>
<h1>Hello Style!</h1>
<p>Add a little style!.</p>
</div>
);
}
}
ReactDOM.render(<MyHeader />, document.getElementById('root'));
Run Example »
CSS Modules
Another way of adding styles to your application is to use CSS Modules.
CSS Modules are convenient for components that are placed in separate files.
The CSS inside a module is available only for the component that imported it,
and you do not have to worry about name conflicts.
Create the CSS module with the .module.css
extension, example: mystyle.module.css
.
mystyle.module.css:
Create a new file called "mystyle.module.css" and insert some CSS code in it:
.bigblue {
color: DodgerBlue;
padding: 40px;
font-family: Arial;
text-align: center;
}
Import the stylesheet in your component:
App.js:
import React from 'react';
import ReactDOM from 'react-dom';
import styles from './mystyle.module.css';
class Car extends React.Component {
render() {
return <h1 className={styles.bigblue}>Hello Car!</h1>;
}
}
export default Car;
Import the component in your application:
index.js:
import React from 'react';
import ReactDOM from 'react-dom';
import Car from './App.js';
ReactDOM.render(<Car />, document.getElementById('root'));
Run Example »
W3 React Sass
What is Sass
Sass is a CSS pre-processor.
Sass files are executed on the server and sends CSS to the browser.
Can I use Sass?
If you use the create-react-app
in your project, you can easily install and use Sass in your React projects.
Install Sass by running this command in your terminal:
C:\Users\Your Name>npm install node-sass
Now you are ready to include Sass files in your project!
Create a Sass file
Create a Sass file the same way as you create CSS files, but Sass files have the file extension .scss
In Sass files you can use variables and other Sass functions:
mysass.scss:
Create a variable to define the color of the text:
$myColor: red;
h1 {
color: $myColor;
}
Import the Sass file the same way as you imported a CSS file:
index.js:
import React from 'react';
import ReactDOM from 'react-dom';
import './mysass.scss';
class MyHeader extends React.Component {
render() {
return (
<div>
<h1>Hello Style!</h1>
<p>Add a little style!.</p>
</div>
);
}
}
ReactDOM.render(<MyHeader />, document.getElementById('root'));
Run Example »
Using the State Hook
https://reactjs.org/docs/hooks-state.html
Hooks are a new addition in React 16.8.
They let you use state and other React features without writing a class.
The introduction page used this example to get familiar with Hooks:
import React, { useState } from 'react';
function Example() {
// Declare a new state variable, which we'll call "count" const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
We’ll start learning about Hooks by comparing this code to an equivalent class example.
Equivalent Class Example
If you used classes in React before, this code should look familiar:
class Example extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
render() {
return (
<div>
<p>You clicked {this.state.count} times</p>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Click me
</button>
</div>
);
}
}
The state starts as { count: 0 }
, and we increment state.count
when the user clicks a button by calling this.setState()
.
We’ll use snippets from this class throughout the page.
Note
You might be wondering why we’re using a counter here instead of a more realistic example.
This is to help us focus on the API while we’re still making our first steps with Hooks.
Hooks and Function Components
As a reminder, function components in React look like this:
const Example = (props) => {
// You can use Hooks here!
return <div />;
}
or this:
function Example(props) {
// You can use Hooks here!
return <div />;
}
You might have previously known these as “stateless components”.
We’re now introducing the ability to use React state from these, so we prefer the name “function components”.
Hooks don’t work inside classes.
But you can use them instead of writing classes.
What’s a Hook?
Our new example starts by importing the useState
Hook from React:
import React, { useState } from 'react';
function Example() {
// ...
}
What is a Hook? A Hook is a special function that lets you “hook into” React features.
For example, useState
is a Hook that lets you add React state to function components.
We’ll learn other Hooks later.
When would I use a Hook? If you write a function component and realize you need to add some state to it, previously you had to convert it to a class.
Now you can use a Hook inside the existing function component.
We’re going to do that right now!
Note:
There are some special rules about where you can and can’t use Hooks within a component.
We’ll learn them in Rules of Hooks.
Declaring a State Variable
In a class, we initialize the count
state to 0
by setting this.state
to { count: 0 }
in the constructor:
class Example extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 }; }
In a function component, we have no this
, so we can’t assign or read this.state
.
Instead, we call the useState
Hook directly inside our component:
import React, { useState } from 'react';
function Example() {
// Declare a new state variable, which we'll call "count" const [count, setCount] = useState(0);
What does calling useState
do? It declares a “state variable”.
Our variable is called count
but we could call it anything else, like banana
.
This is a way to “preserve” some values between the function calls — useState
is a new way to use the exact same capabilities that this.state
provides in a class.
Normally, variables “disappear” when the function exits but state variables are preserved by React.
What do we pass to useState
as an argument? The only argument to the useState()
Hook is the initial state.
Unlike with classes, the state doesn’t have to be an object.
We can keep a number or a string if that’s all we need.
In our example, we just want a number for how many times the user clicked, so pass 0
as initial state for our variable.
(If we wanted to store two different values in state, we would call useState()
twice.)
What does useState
return? It returns a pair of values: the current state and a function that updates it.
This is why we write const [count, setCount] = useState()
.
This is similar to this.state.count
and this.setState
in a class, except you get them in a pair.
If you’re not familiar with the syntax we used, we’ll come back to it at the bottom of this page.
Now that we know what the useState
Hook does, our example should make more sense:
import React, { useState } from 'react';
function Example() {
// Declare a new state variable, which we'll call "count" const [count, setCount] = useState(0);
We declare a state variable called count
, and set it to 0
.
React will remember its current value between re-renders, and provide the most recent one to our function.
If we want to update the current count
, we can call setCount
.
Note
You might be wondering: why is useState
not named createState
instead?
“Create” wouldn’t be quite accurate because the state is only created the first time our component renders.
During the next renders, useState
gives us the current state.
Otherwise it wouldn’t be “state” at all! There’s also a reason why Hook names always start with use
.
We’ll learn why later in the Rules of Hooks.
Reading State
When we want to display the current count in a class, we read this.state.count
:
<p>You clicked {this.state.count} times</p>
In a function, we can use count
directly:
<p>You clicked {count} times</p>
Updating State
In a class, we need to call this.setState()
to update the count
state:
<button onClick={() => this.setState({ count: this.state.count + 1 })}> Click me
</button>
In a function, we already have setCount
and count
as variables so we don’t need this
:
<button onClick={() => setCount(count + 1)}> Click me
</button>
Recap
Let’s now recap what we learned line by line and check our understanding.
1: import React, { useState } from 'react'; 2:
3: function Example() {
4: const [count, setCount] = useState(0); 5:
6: return (
7: <div>
8: <p>You clicked {count} times</p>
9: <button onClick={() => setCount(count + 1)}>10: Click me
11: </button>
12: </div>
13: );
14: }
- Line 1: We import the
useState
Hook from React.
It lets us keep local state in a function component.
- Line 4: Inside the
Example
component, we declare a new state variable by calling the useState
Hook.
It returns a pair of values, to which we give names.
We’re calling our variable count
because it holds the number of button clicks.
We initialize it to zero by passing 0
as the only useState
argument.
The second returned item is itself a function.
It lets us update the count
so we’ll name it setCount
.
- Line 9: When the user clicks, we call
setCount
with a new value.
React will then re-render the Example
component, passing the new count
value to it.
This might seem like a lot to take in at first.
Don’t rush it! If you’re lost in the explanation, look at the code above again and try to read it from top to bottom.
We promise that once you try to “forget” how state works in classes, and look at this code with fresh eyes, it will make sense.
Tip: What Do Square Brackets Mean?
You might have noticed the square brackets when we declare a state variable:
const [count, setCount] = useState(0);
The names on the left aren’t a part of the React API.
You can name your own state variables:
const [fruit, setFruit] = useState('banana');
This JavaScript syntax is called “array destructuring”.
It means that we’re making two new variables fruit
and setFruit
, where fruit
is set to the first value returned by useState
, and setFruit
is the second.
It is equivalent to this code:
var fruitStateVariable = useState('banana'); // Returns a pair
var fruit = fruitStateVariable[0]; // First item in a pair
var setFruit = fruitStateVariable[1]; // Second item in a pair
When we declare a state variable with useState
, it returns a pair — an array with two items.
The first item is the current value, and the second is a function that lets us update it.
Using [0]
and [1]
to access them is a bit confusing because they have a specific meaning.
This is why we use array destructuring instead.
Note
You might be curious how React knows which component useState
corresponds to since we’re not passing anything like this
back to React.
We’ll answer this question and many others in the FAQ section.
Tip: Using Multiple State Variables
Declaring state variables as a pair of [something, setSomething]
is also handy because it lets us give different names to different state variables if we want to use more than one:
function ExampleWithManyStates() {
// Declare multiple state variables!
const [age, setAge] = useState(42);
const [fruit, setFruit] = useState('banana');
const [todos, setTodos] = useState([{ text: 'Learn Hooks' }]);
In the above component, we have age
, fruit
, and todos
as local variables, and we can update them individually:
function handleOrangeClick() {
// Similar to this.setState({ fruit: 'orange' })
setFruit('orange');
}
You don’t have to use many state variables.
State variables can hold objects and arrays just fine, so you can still group related data together.
However, unlike this.setState
in a class, updating a state variable always replaces it instead of merging it.
We provide more recommendations on splitting independent state variables in the FAQ.
Next Steps
On this page we’ve learned about one of the Hooks provided by React, called useState
.
We’re also sometimes going to refer to it as the “State Hook”.
It lets us add local state to React function components — which we did for the first time ever!
We also learned a little bit more about what Hooks are.
Hooks are functions that let you “hook into” React features from function components.
Their names always start with use
, and there are more Hooks we haven’t seen yet.
Now let’s continue by learning the next Hook: useEffect
. It lets you perform side effects in components, and is similar to lifecycle methods in classes.